import type { App } from 'vue'
import { getCurrentInstance } from 'vue'

interface WebSocketConfig {
  url: string
  isReconnect?: boolean
  isClose?: boolean
}

export interface Msg {
  id: string | number
  sendUserId: string | number
  receiveUserId: string | number
  context: string
  type: 1 | 2
  avatar: string
}

export const WebSocket = (app: App) => {
  console.log(app)
}

export class WebSocketClass {
  socketTask = null
  url = ''
  timeout = 10000
  isOpenReconnect = false
  heartbeatInterval = null as any
  reconnectTimeOut = null as any

  constructor(url: string, time: number) {
    this.url = url //地址
    //心跳检测
    this.timeout = time //多少秒执行检测
    this.connectSocketInit()
  }

  // 进入这个页面的时候创建websocket连接【整个页面随时使用】
  connectSocketInit() {
    this.socketTask = uni.connectSocket({
      url: this.url,
      success: () => {
        console.log('websocket连接成功...')
      },
    }) as any

    //打开连接
    ;(this.socketTask as any).onOpen((res: any) => {
      console.log('WebSocket连接正常!')
      clearTimeout(this.reconnectTimeOut)
      clearInterval(this.heartbeatInterval)
      this.isOpenReconnect = true
      this.start()
    })

    //连接关闭时
    ;(this.socketTask as any).onClose((res: any) => {
      console.log(res, '连接已关闭,尝试重新连接')
      this.reconnect()
    })
  }

  onMessage(callback: Function) {
    ;(this.socketTask as any).onMessage((res: any) => {
      console.log(res, 'res')
      callback(res.data)
    })
  }

  start() {
    this.heartbeatInterval = setInterval(() => {
      console.log('心跳检测')
      this.send(
        JSON.stringify({
          type: 'heart',
          msg: '心跳检测',
        })
      )
    }, this.timeout)
  }
  //重新连接
  reconnect() {
    //停止发送心跳
    clearInterval(this.heartbeatInterval)
    //如果不是人为关闭的话，进行重连
    this.reconnectTimeOut = setTimeout(() => {
      if (this.isOpenReconnect) {
        this.connectSocketInit()
      }
    }, 2000)
  }

  send(data: any) {
    ;(this.socketTask as any).send({
      data,
      success() {
        //console.log('心跳检测')
      },
      async fail() {
        this.reconnect()
      },
    })
  }
}
